<script setup lang="ts">
import { SinalService } from '@/server/SinalService';
import { wsUrl } from "@/common/config";
import { onMounted, reactive, ref } from 'vue';
import { Message, TYPE } from '@/server/message';
const localVideoDom = ref<any>();
const remoteVideoDom = ref<any>();
const configuration = { 'iceServers': [{ 'urls': 'stun:stun.l.google.com:19302' }] }
let localVideo: HTMLVideoElement;
let remoteVideo: HTMLVideoElement;
let pc: RTCPeerConnection;
onMounted(() => {
    localVideo = localVideoDom.value;
    remoteVideo = remoteVideoDom.value;
})
let ws: SinalService | null = null;
const room = reactive({
    roomId: "",
    mainUser: "",
    user: [] as Array<string>,
    roomLock: false
});

function join(msg: Message) {
    room.user = msg.data;
    console.log("join:----", room.user);
    if (room.user.length >= 1) {
        //发起视频协商
        console.log("开始...");
        pc = new RTCPeerConnection(configuration);
        pc.onicecandidate = event => {
            ws?.sendTo('candidate', event.candidate);
        };
        pc.onnegotiationneeded = () => {
            pc.createOffer().then(setLocalDescription).catch((e) => {
                console.error(e);
            });
        }
        pc.ontrack = event => {
            console.log("打印html", remoteVideo);
            if (remoteVideo) {
                remoteVideo.srcObject = event.streams[0];
            }
        }
        navigator.mediaDevices.getUserMedia({
            audio: true,
            video: {
                width: 300,
                height: 150
            },
        }).then(stream => {
            // Display your local video in #localVideo element
            localVideo.srcObject = stream;
            // Add your stream to be sent to the conneting peer
            stream.getTracks().forEach(track => pc.addTrack(track, stream));
        }).catch(e => {
            console.log(e);
        });
    }
}
function setLocalDescription(desc: any) {
    pc.setLocalDescription(desc).then((d) => {
        ws?.sendTo("sdp", pc.localDescription);
    }).catch((e) => console.log(e));
}
function setRemoteDescription(message: any) {

    pc.setRemoteDescription(new RTCSessionDescription(message.data)).then(() => {
        console.log("setRemoteDescription:", pc.remoteDescription);
        if (pc && pc.remoteDescription && pc.remoteDescription.type === 'offer') {
            pc.createAnswer().then(setLocalDescription).catch(e => console.log(e));
        }
    }).catch(e => console.log(e));
}
function addIceCandidate(message: any) {
    console.log("addIceCandidate", message.data);
    pc.addIceCandidate(new RTCIceCandidate(message.data));
}


function leaveRoom() {
    room.roomLock = false;
    stopStreamedVideo(localVideo)
    stopStreamedVideo(remoteVideo)
    if (ws) {
        ws.leave();
    }
}

function onMsg(msg: Message) {
    console.log("收到消息:", msg);
}

function offer(msg: Message) {
    console.log("收到offer", msg);
}
function leave(msg: Message) {
    const user = room.user.filter((u) => u !== msg.sender);
    console.log("离开:", msg.sender);
    room.user = user;
    stopStreamedVideo(remoteVideo)
}

function inputRoom() {
    //过滤掉除字母与数字以外的
    room.roomId = room.roomId.replace(/[^a-z0-9]/gi, "");
}

function logUser() {
    console.log(room);
}

function joinRoom() {
    if (!room.roomId) {
        alert("请输入房间ID");
        return;
    }
    room.roomLock = true;
    ws = new SinalService(wsUrl, room.roomId);
    room.mainUser = ws.uid;
    ws.on(TYPE.join, join);
    ws.on(TYPE.offer, offer);
    ws.on(TYPE.leave, leave);
    ws.on(TYPE.msg, onMsg);
    ws.on("sdp", setRemoteDescription);
    ws.on("candidate", addIceCandidate);
    ws.on("full", full);
}
function full(msg: Message) {
    alert(msg.data)
}
function stopStreamedVideo(videoElem: any) {
    const stream = videoElem.srcObject;
    if (stream) {
        const tracks: any[] = stream.getTracks();
        if (tracks) {
            tracks.forEach(function (track) {
                track.stop();
            });
        }
        videoElem.srcObject = null;
    }

}
</script>
<template>
    <video ref="localVideoDom" autoplay muted style="margin: 10px; background-color: bisque;" />
    <video ref="remoteVideoDom" autoplay style="margin: 10px; background-color: bisque;" />
    <br />
    <el-input v-model="room.roomId" @input="inputRoom" :disabled="room.roomLock" class="input" style="width: 150px;"
        placeholder="输入房间"></el-input>
    <el-button :disabled="room.roomLock" type="primary" @click=joinRoom>加入房间</el-button>
    <el-button type="primary" @click=logUser>在线人数</el-button>
    <el-button :disabled="!room.roomLock" type="primary" @click=leaveRoom>退出房间</el-button>
</template>
<style>
.input {
    margin: 10px;
}
</style>